package com.gitee.chili.leisure.util;

import cn.hutool.json.JSONUtil;
import com.gitee.chili.leisure.ResponseResult;
import com.gitee.chili.leisure.constant.Constant;
import com.netflix.zuul.context.RequestContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * GatewayUtil
 *
 * @author week solider
 * @since 2020-07-28
 */
@Slf4j
public class GatewayUtil {

    /**
     * 请求无效时，做出响应
     *
     * @param ctx     当前请求上下文
     * @param message 错误消息
     */
    public static void invalidRequest(RequestContext ctx, String message) {
        ResponseResult<Object> responseResult;
        ctx.setSendZuulResponse(false);
        ctx.setResponseStatusCode(HttpStatus.OK.value());
        if (StringUtils.isEmpty(message)) {
            responseResult = ResponseResult.errorSign();
        } else {
            responseResult = ResponseResult.errorSign(message);
        }
        ctx.setResponseBody(JSONUtil.toJsonStr(responseResult));
    }

    /**
     * json 请求处理
     */
    public static boolean isJsonRequest(String method, String contentType) {
        boolean pass = isPost(method) && contentType.contains(Constant.APPLICATION_JSON);
        if (log.isDebugEnabled())
            log.debug("{}请求是否通过: {}", method, pass);
        return pass;
    }

    /**
     * 表单请求处理
     */
    public static boolean isFormRequest(String method, String contentType) {
        boolean pass = (contentType.contains(Constant.FORM_URLENCODED)) &&
                isPost(method);
        if (log.isDebugEnabled())
            log.debug("{}请求是否通过: {}", method, pass);
        return pass;
    }

    /**
     * 只处理post请求
     */
    public static boolean isPost(String method) {
        return "POST".equalsIgnoreCase(method);
    }

    /**
     * 检查
     *
     * @param timestamp 请求时间戳
     * @return if true is success
     */
    public static boolean isTimestamp(String timestamp) {
        if (StringUtils.isEmpty(timestamp))
            return true;
        long requestTime = Long.parseLong(timestamp);
        if (timestamp.length() > 10)
            return System.currentTimeMillis() - requestTime > Constant.TIMESTAMP_TIMEOUT;
        else
            return (System.currentTimeMillis() / 1000) - requestTime > Constant.TIMESTAMP_TIMEOUT;
    }

    public static void setHeader(HttpServletRequest request, HttpServletResponse response) {
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Expose-Headers", "X-forwarded-port, X-forwarded-host");
        response.setHeader("Vary", "Origin,Access-Control-Request-Method,Access-Control-Request-Headers");
    }

    public static String requestAddr(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (StringUtils.hasLength(ip) && !"unKnown".equalsIgnoreCase(ip)) {
            //多次反向代理后会有多个ip值，第一个ip才是真实ip
            int index = ip.indexOf(",");
            if (index != -1) {
                return ip.substring(0, index);
            } else {
                return ip;
            }
        }
        ip = request.getHeader("X-Real-IP");
        if (StringUtils.hasLength(ip) && !"unKnown".equalsIgnoreCase(ip)) {
            return ip;
        }
        return request.getRemoteAddr();
    }

    public static boolean isLocalAddr(HttpServletRequest request) {
        String ip = requestAddr(request);
        return ip.equals("127.0.0.1") || ip.equals("localhost") || ip.equals("0:0:0:0:0:0:0:1");
    }

    public static void startVerifySign(){
        log.info("============================= start verify sign ==========================");
    }

    public static void endVerifySign(boolean result){
        log.info("verify sign result : [ {} ]", result);
        log.info("============================= end verify sign ==========================");
    }
}

